package com.cola.aop;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;

/**
 * @Grup:com.cola.aop
 * @Auther:cola
 * @Data:2021/4/7-2021-04-22:50
 * @version:1.0
 */
public class BeanFactory {
    Properties prop=new Properties();

    public BeanFactory(InputStream in) {
        try {
            prop.load(in);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /*
    * 获取一个bean实例
    * */
    public Object getBean(String name){
        String className = prop.getProperty(name);
        Object bean =null;
        try {
            //获取proxyFactoryBean的class对象
            Class<?> aClass=Class.forName(className);
            bean=aClass.getDeclaredConstructor().newInstance();//实例化对象
            //根据配置文件实例化target和advice对象
            Object target = Class.forName(prop.getProperty(name + ".target")).getDeclaredConstructor().newInstance();
            Object advice = Class.forName(prop.getProperty(name + ".advice")).getDeclaredConstructor().newInstance();
            //通过内省实现对proxyFactoryBean的属性赋值
            BeanInfo beanInfo = Introspector.getBeanInfo(aClass);
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor pd:propertyDescriptors) {
                String propertyName=pd.getName();
                Method writeMethod=pd.getWriteMethod();
                if ("target".equals(propertyName)){
                    writeMethod.invoke(bean,target);
                }else if ("advice".equals(propertyName)){
                    writeMethod.invoke(bean,advice);
                }
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IntrospectionException e) {
            e.printStackTrace();
        }
        return bean;
    }
}
